package com.dc.service;

import com.dc.constant.Constants;
import com.dc.constant.MessageConstant;
import com.dc.dao.ConfigDao;
import com.dc.dao.ConfigOceanDao;
import com.dc.dao.ShipDao;
import com.dc.dao.ShipRepairDao;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.service.dto.*;
import com.dc.utils.DateUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 单船工序  统计计算
 */
@Service
public class WorkflowStatService {

    @Resource
    private ConfigDao configDao;

//    @Resource
//    private ConfigOceanDao configOceanDao;

    @Resource
    private ShipDao shipDao;

    @Resource
    private ShipRepairDao shipRepairDao;

    @Resource
    private WorkflowService workflowService;

    @Resource
    private CalibrationService calibrationService;

    public List<WorkflowTopFirstEntity> getTopFirst(ShipEntity ship, ShipRepairEntity shipRepairEntity) {

        List<WorkflowTopFirstEntity> result = new ArrayList<>();

        List<WorkflowTopSecondEntity> topSecondList = getTopSecond(ship, shipRepairEntity);

        double sumPower = topSecondList.stream().mapToDouble(WorkflowTopSecondEntity::getPower).sum();
        double sumOil = topSecondList.stream().mapToDouble(WorkflowTopSecondEntity::getOil).sum();
        double sumGas = topSecondList.stream().mapToDouble(WorkflowTopSecondEntity::getGas).sum();
        double sumCo2 = topSecondList.stream().mapToDouble(WorkflowTopSecondEntity::getCo2).sum();

        //配置
        int year = ObjectUtils.isEmpty(shipRepairEntity.getEnterTime()) ? DateUtils.getYear() : DateUtils.getYear(shipRepairEntity.getEnterTime());
        List<ConfigEntity> configList = configDao.findByYear(year);
        Map<String, Double> configMap = new HashMap<>();
        configList.forEach(t -> {
            String name = t.getName();
            Double value = t.getValue();
            configMap.put(name, value);
        });

//        List<ConfigOceanEntity> configOceanList = configOceanDao.findByYear(year);
//        Map<String, Double> configOceanMap = new HashMap<>();
//        configOceanList.forEach(t -> {
//            String name = t.getName();
//            Double value = t.getValue();
//            configOceanMap.put(name, value);
//        });

        // 电力
        WorkflowTopFirstEntity power = new WorkflowTopFirstEntity();
        power.setShipRepairEntity(shipRepairEntity);
        power.setShipName(ship.getName());
        power.setEnergyCategory(Constants.ENERGY_TYPE_SHENZHEN_ELECTRIC);
        power.setUnit("万kWh");
        power.setEnergyAmount(sumPower);
        double factorShenPower = configMap.get(Constants.ENERGY_TYPE_SHENZHEN_ELECTRIC) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_SHENZHEN_ELECTRIC);
        power.setFactorShen(factorShenPower);
        power.setCShen(sumPower * factorShenPower);
        double factorOceanPower = configMap.get(Constants.ENERGY_TYPE_OCEAN_ELECTRIC) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_OCEAN_ELECTRIC);
        power.setFactorOcean(factorOceanPower);
        power.setCOcean(sumPower * factorOceanPower);

        result.add(power);

        // 柴油
        WorkflowTopFirstEntity oil = new WorkflowTopFirstEntity();
        oil.setShipRepairEntity(shipRepairEntity);
        oil.setShipName(ship.getName());
        oil.setEnergyCategory(Constants.ENERGY_TYPE_SHENZHEN_OIL);
        oil.setUnit("t");
        oil.setEnergyAmount(sumOil);
        double factorShenOil = configMap.get(Constants.ENERGY_TYPE_SHENZHEN_OIL) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_SHENZHEN_OIL);
        oil.setFactorShen(factorShenOil);
        oil.setCShen(sumOil * factorShenOil);
        double factorOceanOil = configMap.get(Constants.ENERGY_TYPE_OCEAN_OIL) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_OCEAN_OIL);
        oil.setFactorOcean(factorOceanOil);
        oil.setCOcean(sumOil * factorOceanOil);

        result.add(oil);

        // 天然气
        WorkflowTopFirstEntity gas = new WorkflowTopFirstEntity();
        gas.setShipRepairEntity(shipRepairEntity);
        gas.setShipName(ship.getName());
        gas.setEnergyCategory(Constants.ENERGY_TYPE_SHENZHEN_GAS);
        gas.setUnit("t");
        gas.setEnergyAmount(sumGas);
        double factorShenGas = configMap.get(Constants.ENERGY_TYPE_SHENZHEN_GAS) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_SHENZHEN_GAS);
        gas.setFactorShen(factorShenGas);
        gas.setCShen(sumGas * factorShenGas);
        double factorOceanGas = configMap.get(Constants.ENERGY_TYPE_OCEAN_GAS) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_OCEAN_GAS);
        gas.setFactorOcean(factorOceanGas);
        gas.setCOcean(sumGas * factorOceanGas);

        result.add(gas);

        // 二氧化碳
        WorkflowTopFirstEntity co2 = new WorkflowTopFirstEntity();
        co2.setShipRepairEntity(shipRepairEntity);
        co2.setShipName(ship.getName());
        co2.setEnergyCategory(Constants.ENERGY_TYPE_SHENZHEN_CO2);
        co2.setUnit("t");
        co2.setEnergyAmount(sumCo2);
        double factorShenCo2 = configMap.get(Constants.ENERGY_TYPE_SHENZHEN_CO2) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_SHENZHEN_CO2);
        co2.setFactorShen(factorShenCo2);
        co2.setCShen(sumCo2 * factorShenCo2);
        double factorOceanCo2 = configMap.get(Constants.ENERGY_TYPE_OCEAN_CO2) == null ? 0. : configMap.get(Constants.ENERGY_TYPE_OCEAN_CO2);
        co2.setFactorOcean(factorOceanCo2);
        co2.setCOcean(sumCo2 * factorOceanCo2);

        result.add(co2);

        return result;
    }


    public List<WorkflowTopSecondEntity> getTopSecond(ShipEntity ship, ShipRepairEntity shipRepairEntity) {

        List<WorkflowTopThirdEntity> topThird = getTopThird(ship, shipRepairEntity);

        List<WorkflowTopSecondEntity> result = new ArrayList<>();

        AtomicReference<Double> sumAir = new AtomicReference<>(0.);

        Map<String, List<WorkflowTopThirdEntity>> collect = topThird.stream()
                .collect(Collectors.groupingBy(WorkflowTopThirdEntity::getRoom));
        collect.forEach((room, v)->{
            WorkflowTopSecondEntity topSecond = new WorkflowTopSecondEntity();

            WorkflowTopThirdEntity third = v.get(0);

            topSecond.setShipRepairEntity(third.getShipRepairEntity());
            topSecond.setShipName(third.getShipName());
            topSecond.setRoom(room);

            topSecond.setPower(v.stream().mapToDouble(WorkflowTopThirdEntity::getPower).sum());
            topSecond.setOil(v.stream().mapToDouble(WorkflowTopThirdEntity::getOil).sum());
            topSecond.setGas(v.stream().mapToDouble(WorkflowTopThirdEntity::getGas).sum());
            topSecond.setCo2(v.stream().mapToDouble(WorkflowTopThirdEntity::getCo2).sum());
            topSecond.setO2(v.stream().mapToDouble(WorkflowTopThirdEntity::getO2).sum());
            topSecond.setAir(v.stream().mapToDouble(WorkflowTopThirdEntity::getAir).sum());

            sumAir.updateAndGet(v1 -> v1 + topSecond.getAir());

            result.add(topSecond);
        });

        // 气站
        WorkflowTopSecondEntity airSecondEntity = new WorkflowTopSecondEntity();
        airSecondEntity.setShipRepairEntity(shipRepairEntity);
        airSecondEntity.setShipName(ship.getName());
        airSecondEntity.setRoom(Constants.WORK_FLOW_ROOM_AIR);

        Double unitAirPower = calibrationService.calcUnitAirPower();
        airSecondEntity.setPower(unitAirPower * sumAir.get());

        result.add(airSecondEntity);

        return result;
    }

    public List<WorkflowTopThirdEntity> getTopThird(ShipEntity ship, ShipRepairEntity shipRepairEntity) {

        List<WorkflowTopThirdEntity> result = new ArrayList<>();

        Long shipRepairId = shipRepairEntity.getId();

        // 移动电箱
        List<WorkflowElectricBoxDto> electricBoxDtoList = workflowService.calcElectricBox(shipRepairId);
        electricBoxDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setPower(t.getPower());

            result.add(entity);
        });

        // 0 船体下料
        List<WorkflowShipCutDto> shipCutDtoList = workflowService.calcShipCut(shipRepairId);
        shipCutDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setO2(t.getO2());
            entity.setAir(t.getAir());

            result.add(entity);
        });

        // 1 船体割旧
        List<WorkflowShipOldDto> shipOldDtoList = workflowService.calcShipOld(shipRepairId);
        shipOldDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setGas(t.getGas());
            entity.setO2(t.getO2());

            result.add(entity);
        });

        // 2 船体焊接
        List<WorkflowShipWeldDto> shipWeldDtoList = workflowService.calcShipWeld(shipRepairId);
        shipWeldDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setCo2(t.getCo2());
            entity.setPower(t.getPower());

            result.add(entity);
        });

        // 3 机电管子焊接
        List<WorkflowMachinePipeDto> machinePipeDtoList = workflowService.calcMachinePipe(shipRepairId);
        machinePipeDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setPower(t.getPower());

            result.add(entity);
        });

        // 4 拖船油耗
        List<WorkflowTowShipOilDto> towShipOilDtoList = workflowService.calcTowShipOil(shipRepairId);
        towShipOilDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setOil(t.getOil());

            result.add(entity);
        });

        // 5-0 其他油耗-单船
        List<WorkflowOtherOilShipDto> otherOilShipDtoList = workflowService.calcOtherOilShip(shipRepairId);
        otherOilShipDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setOil(t.getOil());

            result.add(entity);
        });

        // 5-1 其他油耗-高空车
        List<WorkflowOtherOilCarDto> otherOilCarDtoList = workflowService.calcOtherOilCar(shipRepairId);
        otherOilCarDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setOil(t.getOil());

            result.add(entity);
        });

        // 6-0 涂装喷漆-舱室及船壳喷漆
        List<WorkflowPaintShipDto> paintShipDtoList = workflowService.calcPaintShip(shipRepairId);
        paintShipDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setAir(t.getAir());

            result.add(entity);
        });

        // 6-1 涂装喷漆-喷漆房分段喷漆
        List<WorkflowPaintHouseDto> paintHouseDtoList = workflowService.calcPaintHouse(shipRepairId);
        paintHouseDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setPower(t.getPower());
            entity.setGas(t.getGas());
            entity.setAir(t.getAir());

            result.add(entity);
        });

        // 7-0 打砂除锈-舱室打砂
        List<WorkflowShipSandDto> shipSandDtoList = workflowService.calcShipSand(shipRepairId);
        shipSandDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setAir(t.getAir());

            result.add(entity);
        });

        // 7-1 打砂除锈-打砂房分段打砂
        List<WorkflowHouseSandDto> houseSandDtoList = workflowService.calcHouseSand(shipRepairId);
        houseSandDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setPower(t.getPower());
            entity.setAir(t.getAir());

            result.add(entity);
        });

        // 8 超水除锈
        List<WorkflowWaterCleanDto> waterCleanDtoList = workflowService.calcWaterClean(shipRepairId);
        waterCleanDtoList.forEach(t->{
            WorkflowTopThirdEntity entity = setCommonFields(ship, shipRepairEntity);

            entity.setRoom(t.getRoom());
            entity.setWorkflow(t.getName());

            entity.setPower(t.getPower());

            result.add(entity);
        });

        return result;
    }

    private WorkflowTopThirdEntity setCommonFields(ShipEntity ship, ShipRepairEntity shipRepairEntity) {
        WorkflowTopThirdEntity entity = new WorkflowTopThirdEntity();
        entity.setShipRepairEntity(shipRepairEntity);
        entity.setShipName(ship.getName());

        return entity;
    }
}
